home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Sample Code / Snippets / QuickTime / MCActionProc / PlayerExample.c < prev    next >
Encoding:
Text File  |  1994-10-28  |  26.9 KB  |  1,060 lines  |  [TEXT/MMCC]

  1. // This is based on the sample code on the QuickTime 1.5 CD ROM
  2. //
  3. //    Movie controller components allow you to create an action filter function in your 
  4. //    application. The component calls your action filter function whenever an action 
  5. //    occurs in the control. (An action is an integer constant used by the movie controller 
  6. //    omponent.) You can then customize the behavior of the control or simply monitor user 
  7. //    actions. You establish an action filter function by calling the MCSetActionFilter 
  8. //    function.
  9. //    
  10. //    This code  demonstrates the use of an action filter function, and handles 
  11. //    mouse down events in the content region of the movie window, allowing a user to 
  12. //  navigate in the movie by dragging left and right. This filter function 
  13. //    resizes the window whenever the user hides the controller. Therefore, this example 
  14. //    function handles the mcActionControllerSizeChanged action. Your application should 
  15. //    include a similar action filter function so that you can determine when the user 
  16. //    resizes the controller. 
  17. //
  18. //     The code also gets around a QuickTime 2.0 problem with the drag manager
  19. //
  20. //         MCDoAction( aController, mcActionSetDragEnabled, (void *)false) ;
  21. //
  22. //     does not work quite as expected, the DoIgnoreDrags() workaround lets us ignore
  23. //     both dragging and dropping
  24. //
  25. //     10/10/94        nick        stripped code from the text media example
  26. //    10/17/94        nick        added an MCActionProc, this allows you to move backwards
  27. //                                and forwards through the movie by dragging left and right on 
  28. //                                the movie.
  29. //    10/18/94        nick        added code to turn off drag manager support in QT 2.0
  30. //
  31. //    Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  32.  
  33.  
  34. #include "mtb.h"
  35. #include "QDOffscreen.h"
  36. #include <FixMath.h>
  37.  
  38. void    AdornWindow( WindowPtr whichWindow, const RGBColor *adornerColor ) ;
  39. void    DoCreateMovieWindow( void ) ;
  40. void    DoDestroyMovieWindow( WindowPtr aWindow ) ;
  41. void     MainEventLoop( void ) ;
  42. void     InitMac( void ) ;
  43. Boolean IsAppWindow(WindowPtr window) ;
  44. void     HandleKeyPress( EventRecord *event ) ;
  45. void     HandleMenuCommand(long menuResult ) ;
  46. void    AdjustMenus( void ) ;
  47.  
  48. Track    GetFirstTrackOfType( Movie    aMovie, OSType    trackType ) ;
  49. OSErr    DoPrerollMovie( Movie    aMovie ) ;
  50. pascal     Boolean myMCActionFilter(MovieController mc, short action, void *params, long refCon) ;
  51. void     DoSelectActive( WindowPtr whichWindow ) ;
  52. void     DoAdjustCursor( Point mouse, RgnHandle region, WindowPtr window) ;
  53. OSErr    DoIgnoreDrags( MovieController    aController ) ;
  54.  
  55. #define HiWrd(aLong)    (((aLong) >> 16) & 0xFFFF)
  56. #define LoWrd(aLong)    ((aLong) & 0xFFFF)
  57.  
  58.  
  59. //---------------------------------------------------------------------------
  60. // define a record to hold the information we need for each movie window.
  61. // The movie can be gotten from the movieController
  62. //---------------------------------------------------------------------------
  63.  
  64. typedef    struct    {
  65.     MovieController        myController ;
  66. } DocumentRecord, *DocumentPtr, **DocumentHandle ;
  67.  
  68. //---------------------------------------------------------------------------
  69.  
  70. static Boolean    gQuitFlag    = false ;            // set to true when we want to quit
  71.  
  72. const        RGBColor    kWindowBGColor     = {0xFF00, 0xFF00, 0xFF00} ;    // grays made the caret yellow, ughh, need to investigate this
  73. const         RGBColor    kRGBBlack     = {0x0000, 0x0000, 0x0000} ;
  74. const         RGBColor     kRGBGray     = {0xAAAA, 0xAAAA, 0xAAAA} ;
  75. const         RGBColor    kRGBWhite     = {0xFFFF, 0xFFFF, 0xFFFF} ;
  76.  
  77. const        Rect        kDefaultWinRect ;
  78. const        short        kSlopMargin = 8 ;
  79.  
  80.  
  81.  
  82. //---------------------------------------------------------------------
  83. //
  84. // menus and items...
  85.  
  86. enum {
  87.     mApple = 128,
  88.     mFile,
  89.     mEdit
  90. } ;
  91.  
  92. enum {
  93.     iAbout = 1
  94. } ;
  95. enum {
  96.     iOpen = 1,
  97.     iClose,
  98.     iUnused1,
  99.     iSaveAs = 4,
  100.     iUnused2,
  101.     iQuit
  102.     
  103. } ;
  104.  
  105. enum {
  106.     iUndo = 1,
  107.     iCut = 3,
  108.     iCopy,
  109.     iPaste,
  110.     iClear,
  111.     iSelectAll = 8
  112. } ;
  113.  
  114. //---------------------------------------------------------------------
  115.  
  116. DocumentHandle        CreateDocumentHandle( WindowPtr    aWindow )
  117. {
  118.     DocumentHandle    theHandle ;
  119.     
  120.     theHandle = (DocumentHandle)NewHandle( sizeof(DocumentRecord)) ;
  121.     if( theHandle != nil ) {
  122.     
  123.         // make sure we init the doc record fields to sensible values.
  124.         
  125.         (**theHandle).myController = nil ;
  126.         
  127.         // store a reference to the document record for this window 
  128.         // in the refcon field of this window.
  129.         SetWRefCon ( aWindow, (long)theHandle );
  130.  
  131.     }
  132.     
  133.     return    theHandle ;
  134. }
  135.  
  136. //---------------------------------------------------------------------
  137.  
  138. WindowPtr    CreateMovieWindow( Rect *aRect, Str255 theTitle ) 
  139. {
  140.     WindowPtr            aWindow ;
  141.  
  142.     // create a window for the movie
  143.     aWindow = NewCWindow(nil, 
  144.                             aRect, 
  145.                             theTitle, 
  146.                             false, 
  147.                             noGrowDocProc, 
  148.                             (WindowPtr)-1, 
  149.                             true, 
  150.                             0 ) ;
  151.     
  152.     // restore current port
  153.     return aWindow ;
  154. }
  155.  
  156. //---------------------------------------------------------------------
  157. // turn off drag manager support
  158.  
  159. OSErr    DoIgnoreDrags( MovieController    aController )
  160. {
  161.     // these two are used to hack the drag manager support
  162.     GWorldPtr            tempGWorld ;
  163.     Rect                tempRect = { 0,0, 20,20} ;
  164.     OSErr                myErr = noErr ;
  165.     CGrafPtr            port ;
  166.     GDHandle            gdh ;
  167.     
  168.     // the following code gets around a QuickTime 2.0 problem
  169.     // with the drag manager
  170.     //
  171.     //         MCDoAction( aController, mcActionSetDragEnabled, (void *)false) ;
  172.     //
  173.     // does not work quite as expected, the following workaround lets us ignore
  174.     // both dragging and dropping
  175.     
  176.     // set up so we ignore drags
  177.     if((myErr = NewGWorld( &tempGWorld, 1, &tempRect, nil, nil, 0L )) == noErr)
  178.     {
  179.         // get the current port
  180.         port = MCGetControllerPort( aController ) ;
  181.         
  182.         // set the movie controller port to the new offscreen
  183.         MCSetControllerPort( aController, (CGrafPtr)tempGWorld ) ;
  184.         
  185.         // tell 'em we don't want drags
  186.         MCDoAction( aController, mcActionSetDragEnabled, (void *)false) ;
  187.  
  188.         // restore the movie controller port
  189.         MCSetControllerPort( aController, port ) ;
  190.         
  191.         // ditch the offscreen
  192.         DisposeGWorld( tempGWorld ) ;
  193.     }
  194.     
  195.     return myErr ;
  196. }    
  197.  
  198. //---------------------------------------------------------------------
  199.  
  200. MovieController    SetUpMovieWindowWithController( WindowPtr    aWindow ) 
  201. {
  202.     Movie                 aMovie ;        // the movie in question
  203.     MovieController        aController;    // the controller for this movie
  204.     Rect                aRect ;            // bounding rect of the movie
  205.     GrafPtr                savedPort ;        // used to reset the current port
  206.     DocumentHandle        aDocHdl ;
  207.     short                movieWidth ;
  208.     short                movieHeight ;
  209.     Boolean                boolValue = false ;
  210.     
  211.  
  212.     aDocHdl = (DocumentHandle)GetWRefCon( aWindow ) ;
  213.  
  214.     // save whatever the port was before we go in here
  215.     GetPort( &savedPort ) ;
  216.     
  217.      // get the movie to open
  218.      aMovie = GetMovie () ;
  219.      
  220.      // sanity check
  221.     if( aMovie == nil )
  222.         CheckError( paramErr, "\pSetUpMovieWindowWithController was passed nil for aMovie") ;
  223.  
  224.      SetPort( (GrafPtr)aWindow ) ;
  225.      
  226.      // set the movies environment to the current
  227.     // port and gDevice (pass nil for defaults)
  228.     SetMovieGWorld( aMovie, nil, nil ) ;
  229.     
  230.     // Use the movie bounding rect to size the movie
  231.     GetMovieBox( aMovie, &aRect );    
  232.     OffsetRect( &aRect, -aRect.left, -aRect.top ) ;
  233.     SetMovieBox( aMovie, &aRect );    
  234.  
  235.     // create a movie controller for the movie
  236.     aController = NewMovieController (aMovie, &aRect, 0L | mcTopLeftMovie );
  237.         
  238.     MCGetControllerBoundsRect(aController,&aRect) ;
  239.  
  240.     // lets make sure the movie bounds are reasonable
  241.     movieWidth = aRect.right - aRect.left ;
  242.     movieHeight = aRect.bottom - aRect.top ;
  243.     aRect.top = aRect.left = 0 ;
  244.     aRect.right = movieWidth ;
  245.     aRect.bottom = movieHeight ;
  246.  
  247.     // size the window accordingly
  248.     SizeWindow( aWindow, movieWidth, movieHeight, true ) ;
  249.     MoveWindow( aWindow, 50, 50, false ) ;
  250.     
  251.     // should have some error handling here
  252.     if (aController == nil) 
  253.         ExitToShell();
  254.  
  255.     // install our event filter
  256.  
  257.     MCSetActionFilterWithRefCon( aController, NewMCActionFilterWithRefConProc(myMCActionFilter), 0L) ;
  258.  
  259.     // store the controller in the document record
  260.     (**aDocHdl).myController = aController ;
  261.     
  262.     DoIgnoreDrags( aController ) ;
  263.     
  264.     SetPort( savedPort ) ;
  265.     return aController ;
  266. }    
  267.  
  268.  
  269. //---------------------------------------------------------------------
  270.  
  271. void    DoCreateMovieWindow() 
  272. {
  273.     Rect                         aRect = kDefaultWinRect ;
  274.     Rect                        controlRect ;                 // for the push button control
  275.     WindowPtr                     aWindow;
  276.     Track                        aTrack ;
  277.     ControlHandle                aControl ;
  278.     MovieController                aController ;
  279.     DocumentHandle                theDocHandle ;
  280.     GrafPtr                        savedPort ;
  281.         
  282.         
  283.     GetPort( &savedPort ) ;
  284.     
  285.     // create the window
  286.     aWindow = CreateMovieWindow( &aRect, "\pA Movie" ) ;
  287.     SetPort( (GrafPtr)aWindow ) ;
  288.     
  289.     if( aWindow == nil ) 
  290.         CheckError( -1, "\pCouldn't create window") ;
  291.     
  292.     // set up our document handle in the refcon field of the window
  293.     theDocHandle = CreateDocumentHandle( aWindow ) ;
  294.     if( theDocHandle == nil ) 
  295.         CheckError( MemError(), "\pCouldn't allocate memory") ;
  296.         
  297.     
  298.     // set up the movie for the window
  299.     aController = SetUpMovieWindowWithController( aWindow ) ;
  300.         
  301.     // finally show the window.
  302.     ShowWindow ( aWindow );
  303.  
  304.     // 
  305.     InvalRect( &((GrafPtr)aWindow)->portRect ) ;
  306.     
  307.     // set up the edit menu
  308.     MCEnableEditing( aController, true ) ;
  309.  
  310.     SetPort( savedPort ) ;
  311.  
  312. }
  313.  
  314. //---------------------------------------------------------------------
  315.  
  316. OSErr DoPrerollMovie( Movie    aMovie ) 
  317. {
  318.     TimeValue         aTimeValue ;
  319.     TimeValue         movieDur ;
  320.     Fixed             preferredRate ;
  321.     OSErr            theErr = noErr ;
  322.  
  323.     aTimeValue = GetMovieTime(aMovie, nil);
  324.     movieDur = GetMovieDuration(aMovie);
  325.     preferredRate = GetMoviePreferredRate(aMovie);
  326.  
  327.     if (aTimeValue == movieDur) 
  328.         aTimeValue = 0;
  329.         
  330.     theErr = PrerollMovie(aMovie, aTimeValue, preferredRate);
  331.  
  332.     return theErr ;
  333. }
  334.  
  335. //---------------------------------------------------------------------
  336.  
  337. void    DoDestroyMovieWindow( WindowPtr aWindow )
  338. {
  339.     Movie                aMovie ;
  340.     MovieController        aController ;
  341.     DocumentHandle        aDocHdl ;
  342.     
  343.     aDocHdl = (DocumentHandle)GetWRefCon( aWindow ) ;
  344.     aController = (**aDocHdl).myController ;
  345.         
  346.     if( aController != nil ) {
  347.         aMovie = MCGetMovie( aController ) ;
  348.         if( aMovie != nil ) {
  349.             DisposeMovie (aMovie);
  350.         }
  351.         DisposeMovieController (aController);
  352.     }
  353.     
  354.     DisposeWindow(aWindow);
  355. }
  356.  
  357. //---------------------------------------------------------------------
  358.  
  359. Boolean    PointInMovieController( MovieController    aController, WindowPtr whichWindow, Point where)
  360. {
  361.     RgnHandle        rgn ;
  362.     Boolean            result = false ;
  363.     
  364.     rgn = MCGetWindowRgn( aController, whichWindow ) ;
  365.     if( rgn != nil ) {
  366.         result = PtInRgn( where, rgn ) ;
  367.         DisposeRgn( rgn ) ;
  368.     }
  369.     return result ;
  370. }
  371.  
  372.  
  373.  
  374. //---------------------------------------------------------------------
  375.  
  376. void    HandleContentClick( WindowPtr whichWindow, EventRecord *theEvent )
  377. {
  378.     GrafPtr            oldPort ;
  379.     // stub    
  380.     
  381.     GetPort(&oldPort ) ;    
  382.     SetPort( whichWindow );
  383.     
  384.     SetPort( oldPort ) ;
  385. }
  386.  
  387. //---------------------------------------------------------------------
  388.  
  389. void    MyDoIdle( WindowPtr whichWindow ) 
  390. {
  391.     GrafPtr                oldPort ;
  392.     DocumentHandle        aDocHdl ;
  393.     MovieController    aController = nil;
  394.     
  395.     GetPort(&oldPort ) ;    
  396.     SetPort( whichWindow );
  397.     
  398.     if((aDocHdl = (DocumentHandle)GetWRefCon( whichWindow )) != nil )
  399.         if((aController = (**aDocHdl).myController) != nil)
  400.              MoviesTask( MCGetMovie(aController), 0);    
  401.  
  402.     SetPort( oldPort ) ;
  403.  
  404. }
  405.  
  406. //---------------------------------------------------------------------
  407.  
  408. void    DoActivateWindow( WindowPtr    whichWindow, Boolean becomingActive) 
  409. {
  410.     DocumentHandle        aDocHdl ;            // our document record is stuffed in the window refcon
  411.     MovieController        aController ;
  412.     GrafPtr                savedPort ;
  413.  
  414.     GetPort(&savedPort) ;
  415.     SetPort((GrafPtr)whichWindow) ;
  416.  
  417.     if((aDocHdl = (DocumentHandle)GetWRefCon(whichWindow)) != nil)
  418.         if((aController = (**aDocHdl).myController) != nil ) 
  419.             MCActivate( aController, whichWindow, becomingActive ) ;
  420.  
  421.     SetPort(savedPort) ;
  422. }
  423.  
  424.  
  425.  
  426. //---------------------------------------------------------------------
  427.  
  428. void    DoUpdateWindow( WindowPtr whichWindow, Rect *refreshArea )
  429. {
  430.     GrafPtr            savedPort ;
  431.     
  432.     GetPort(&savedPort ) ;    
  433.     SetPort( whichWindow );
  434.  
  435.     BeginUpdate (whichWindow);
  436.  
  437.     // draw whatever in here, as the movie controller handles updates for the movie
  438.     // and the controller, we don't have anything else in the window to update
  439.  
  440.     EndUpdate (whichWindow);
  441.     SetPort( savedPort ) ;
  442.  
  443. }
  444.  
  445. //---------------------------------------------------------------------
  446.  
  447. void MainEventLoop( void ) 
  448. {
  449.     OSErr                         err;
  450.     EventRecord                 theEvent;
  451.     WindowPtr                     whichWindow, theWindow;
  452.     short                         part;
  453.     short                        controlPart ;
  454.     ControlHandle                aControl ;
  455.     Boolean                        wasMovieEvent ;
  456.     MovieController                aController ;
  457.     Point                        aPoint = {100, 100};
  458.     Rect                         refreshArea ;
  459.     Rect                         screenRect ;
  460.     GrafPtr                        oldPort ;
  461.     
  462.     DocumentHandle                aDocHdl ;
  463.     Boolean                        myMovieIsActive ;
  464.  
  465.     
  466.     // use this in calls to MCDoAction
  467.     long                        myMCActionParams ;
  468.     RgnHandle                    cursorRgn = NewRgn() ;
  469.  
  470.     while (!gQuitFlag) {
  471.  
  472.  
  473.         AdjustMenus() ;
  474.         DoAdjustCursor( theEvent.where, cursorRgn, FrontWindow() ) ;
  475.         
  476.         wasMovieEvent = false ;
  477.         
  478.         WaitNextEvent(everyEvent, &theEvent, 0, nil );
  479.         
  480.         for( theWindow = FrontWindow(); theWindow != nil ; theWindow = (WindowPtr)((WindowPeek)theWindow)->nextWindow)
  481.             if(( aDocHdl = (DocumentHandle)GetWRefCon( theWindow )) != nil)         
  482.                 if( (aController = (**aDocHdl).myController) != nil ) 
  483.                     if(MCIsPlayerEvent(aController, &theEvent)) 
  484.                         wasMovieEvent = true ;
  485.                     
  486.         // if the controller didn't or couldn't handle it
  487.         // we need to handle it in the main event loop.
  488.             
  489.         if (!wasMovieEvent) {
  490.         
  491.             switch (theEvent.what) {
  492.             
  493.                 case mouseDown:
  494.                     
  495.                     part = FindWindow (theEvent.where, &whichWindow);
  496.                                                         
  497.                     switch (part) {
  498.                     
  499.                         case inMenuBar: 
  500.                             HandleMenuCommand(MenuSelect(theEvent.where));
  501.                             break;
  502.                                                         
  503.                         case inDrag:
  504.                             {
  505.                                 Rect             r;
  506.                                 Movie             aMovie ;
  507.                                 MovieController    aController ;
  508.                                 DocumentHandle    aDocHdl ;
  509.                                 
  510.                                 aDocHdl = (DocumentHandle)GetWRefCon( whichWindow ) ;
  511.                                 aController = (**aDocHdl).myController ;
  512.                                 
  513.                                 aMovie =     MCGetMovie(aController) ;
  514.                         
  515.  
  516.                                 GetMovieBox(aMovie, &r);
  517.                                 screenRect = (**GetGrayRgn()).rgnBBox;
  518.                                 DragAlignedWindow(whichWindow, theEvent.where, &screenRect, &r, nil);
  519.                             }
  520.                             break;
  521.                             
  522.                         case inContent:
  523.                             
  524.                             HandleContentClick( whichWindow, &theEvent ) ;
  525.                             break ;
  526.                             
  527.                         case inGoAway:    
  528.  
  529.                             // if the window got closed, dispose of our movie 
  530.                             // and the controller and the window.
  531.                             
  532.                             if( TrackGoAway (whichWindow, theEvent.where ))
  533.                                 DoDestroyMovieWindow( whichWindow ) ;
  534.                                 
  535.                             break;
  536.                     }
  537.                     break ;
  538.                     
  539.                 case updateEvt:
  540.                     
  541.                     whichWindow = (WindowPtr)theEvent.message;                    
  542.                     refreshArea = ((**(whichWindow->visRgn)).rgnBBox);
  543.                     DoUpdateWindow( whichWindow, &refreshArea ) ;
  544.                     break;
  545.                 
  546.                 case keyDown:
  547.                 case autoKey:
  548.                     HandleKeyPress(&theEvent);
  549.                     break;
  550.                     
  551.                 case diskEvt:
  552.                     if ( HiWrd(theEvent.message) != noErr ) 
  553.                         (void) DIBadMount(aPoint, theEvent.message);
  554.                     break;
  555.                     
  556.                 case activateEvt:
  557.                     // so are we becoming active?
  558.                     whichWindow = (WindowPtr)theEvent.message ;
  559.                     if( IsAppWindow(whichWindow)) {
  560.                         DoActivateWindow( whichWindow, ((theEvent.modifiers & activeFlag) != 0)) ;
  561.                     }
  562.                     break;
  563.  
  564.                 case osEvt:
  565.                     switch ((theEvent.message >> 24) & 0x00FF) {        // High byte of message
  566.                         case suspendResumeMessage:
  567.                             if (FrontWindow()) {
  568.                                 DoActivateWindow(FrontWindow(), !((theEvent.message & resumeFlag) == 0));    
  569.                             }
  570.                             break;
  571.  
  572.                         case mouseMovedMessage:
  573.                             break;
  574.                     }
  575.                     break;
  576.                     
  577.                 case nullEvent:
  578.                     if(( whichWindow = FrontWindow()) != nil ) 
  579.                         MyDoIdle( whichWindow ) ;
  580.                     break ;
  581.  
  582.             }
  583.         }
  584.     }
  585.     DisposeRgn( cursorRgn ) ;
  586. }
  587.  
  588. //---------------------------------------------------------------------
  589.  
  590. Boolean IsAppWindow(WindowPtr window)
  591. {
  592.     short        windowKind;
  593.  
  594.     if ( window == nil )
  595.         return false;
  596.     else {
  597.         windowKind = ((WindowPeek) window)->windowKind;
  598.         return ((windowKind >= userKind) || (windowKind == dialogKind));
  599.     }
  600. }
  601.  
  602. //---------------------------------------------------------------------
  603.  
  604. void AdjustMenus( void ) 
  605. {
  606.     WindowPtr            theWindow ;
  607.     MenuHandle            editMenu ;
  608.     MovieController        aController ;
  609.     DocumentHandle        aDocHdl ;
  610.  
  611.  
  612.  
  613.     theWindow = FrontWindow() ;
  614.             
  615.     if( theWindow != nil ) {
  616.         EnableItem ( GetMHandle ( mFile ), iClose );
  617.         
  618.         // The edit menu - let the movie controller setting it up
  619.         if((aDocHdl = (DocumentHandle)GetWRefCon( theWindow )) != nil ) 
  620.         {
  621.             if(aController = (**aDocHdl).myController) {
  622.                 MenuHandle editMenu = GetMHandle( mEdit ) ;
  623.                 MCSetUpEditMenu(aController, 0L, GetMHandle ( mEdit ) ) ;
  624.             }
  625.         }
  626.     }
  627.     else {
  628.         DisableItem ( GetMHandle ( mFile ), iClose );
  629.     }
  630.     DisableItem ( GetMHandle ( mEdit ), 0 );
  631.  
  632. }
  633.  
  634.  
  635. //---------------------------------------------------------------------
  636.  
  637. void HandleKeyPress(EventRecord *event)
  638. {
  639.     char            key;
  640.  
  641.     key = event->message & charCodeMask;
  642.         
  643.     if ( event->modifiers & cmdKey ) {        // Command key down?
  644.         HandleMenuCommand(MenuKey(key));
  645.     } 
  646. }
  647.  
  648.  
  649. //---------------------------------------------------------------------
  650.  
  651. void HandleMenuCommand(long menuResult)
  652. {
  653.     short                menuID;
  654.     short                menuItem;
  655.     Str255                daName;
  656.     DialogPtr            theDialog ; 
  657.     short                itemHit ;
  658.     FSSpec                theFSSpec ;
  659.     OSErr                err ;
  660.     short                theRef ;
  661.     
  662.     Movie                aMovie = nil;
  663.     MovieController        aController ;
  664.     
  665.     StandardFileReply    theSFReply ;
  666.     DocumentHandle        aDocHdl ;
  667.     WindowPtr            aWindow ;
  668.     OSErr                theErr ;
  669.     
  670.     
  671.     menuID = HiWrd(menuResult);
  672.     menuItem = LoWrd(menuResult);
  673.     switch ( menuID ) {
  674.         case mApple:
  675.             switch ( menuItem ) {
  676.                 case iAbout:
  677.                     theDialog = GetNewDialog ( 128, nil, (WindowPtr)-1 );
  678.                     SetDialogDefaultItem(theDialog, 1) ;
  679.  
  680.                     do {
  681.                         ModalDialog ( nil, &itemHit );
  682.                     } while( itemHit != ok ) ;
  683.                     DisposDialog ( theDialog );
  684.                     break;
  685.                     
  686.                 default:
  687.                     GetItem(GetMHandle(mApple), menuItem, daName);
  688.                     (void) OpenDeskAcc(daName);
  689.                     break;
  690.             }
  691.             break;
  692.             
  693.         case mFile:
  694.             switch ( menuItem ) {
  695.                 case iOpen:
  696.                     DoCreateMovieWindow();
  697.                     break ;
  698.                     
  699.                 case iClose:
  700.                     DoDestroyMovieWindow( FrontWindow() ) ;
  701.                     break ;
  702.                     
  703.                 case iSaveAs:
  704.  
  705.  
  706.                     // get the name of the file to save as
  707.                     StandardPutFile("\pSave movie as:", "\pNew Movie File", &theSFReply) ;
  708.                     
  709.                     if( theSFReply.sfGood ) {
  710.                     
  711.                         // get the movie for this window
  712.                         aDocHdl = (DocumentHandle)GetWRefCon( FrontWindow() ) ;
  713.                         aController = (**aDocHdl).myController ;
  714.                     
  715.                         if( aController != nil ) {
  716.                             aMovie = MCGetMovie(aController) ;
  717.                         }
  718.                         else {
  719.                             CheckError( -1, "\pCouldn't get movie controller") ;
  720.                         }
  721.                         
  722.                         if( aMovie != nil ) {
  723.                             
  724.                             FlattenMovieData( aMovie, flattenAddMovieToDataFork, &theSFReply.sfFile, 'TVOD', smSystemScript, createMovieFileDeleteCurFile ) ;
  725.  
  726.                             theErr = GetMoviesError() ;
  727.                             CheckError( theErr, "\pCouldn't FlattenMovieData") ;
  728.                             
  729.                                                         
  730.                         }
  731.                         
  732.                     }
  733.                     break ;
  734.                     
  735.                  case iQuit:
  736.                     gQuitFlag = true;
  737.                     break;
  738.             }
  739.             break;
  740.             
  741.         case mEdit:
  742.         
  743.             if((aWindow = FrontWindow()) != nil ) {
  744.                 aDocHdl = (DocumentHandle)GetWRefCon(aWindow) ;
  745.                 aController = (**aDocHdl).myController ;
  746.             }
  747.             
  748.             switch ( menuItem ) {
  749.             
  750.                 case iUndo:
  751.                     MCUndo( aController ) ;
  752.                     break ;
  753.                     
  754.                 case iCut:
  755.                     aMovie = MCCut( aController ) ;
  756.                     break ;
  757.                     
  758.                 case iCopy:
  759.                     aMovie = MCCopy( aController ) ;
  760.                     break ;
  761.                     
  762.                 case iPaste:
  763.                     MCPaste( aController, nil ) ;
  764.                     break ;
  765.                     
  766.                 case iClear:
  767.                     MCClear( aController ) ;
  768.                     break ;
  769.                     
  770.                 case iSelectAll:
  771.                     break ;
  772.             }
  773.             if( aMovie ) {
  774.                 PutMovieOnScrap( aMovie, 0) ;
  775.                 DisposeMovie( aMovie ) ;
  776.             }
  777.             break ;
  778.             
  779.     }
  780.     HiliteMenu(0);        // Unhighlight whatever MenuSelect or MenuKey hilited
  781. }
  782.  
  783. //---------------------------------------------------------------------
  784.  
  785. void InitMac( void )
  786. {
  787.     Handle        menuBar = nil;
  788.  
  789.     // we want to grow the heap as big as possble, or the text media handler may not 
  790.     // load the text track properly initially
  791.  
  792.     MaxApplZone();
  793.     MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters();
  794.     MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters();
  795.     MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters();
  796.     MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters();
  797.  
  798.     InitGraf (&qd.thePort);
  799.     InitFonts ();
  800.     InitWindows ();
  801.     InitMenus ();
  802.     TEInit ();
  803.     InitDialogs ((long)nil);
  804.     
  805.     if (!IsQuickTimeInstalled()) {
  806.         CheckError(-1,"\pPlease install QuickTime and try again.");
  807.     }
  808.     
  809.     CheckError( EnterMovies (), "\pEnterMovies failed" );    
  810.     
  811.     // get the menu bar
  812.         
  813.     menuBar = GetNewMBar(128);                // Read menus into menu bar, MBAR res id is 128
  814.     
  815.     if ( menuBar == nil )
  816.          ExitToShell();                        // if we dont have it then quit - your app 
  817.                                              // needs a dialog here
  818.  
  819.     SetMenuBar(menuBar);                    // Install menus
  820.     DisposHandle(menuBar);
  821.     
  822.     AddResMenu(GetMHandle(mApple), 'DRVR');    // Add DA names to Apple menu, ID 128
  823.  
  824.     DrawMenuBar();
  825.  
  826.     
  827.     gQuitFlag = false ;                    // set the flag for the main event loop
  828. }
  829.  
  830. //---------------------------------------------------------------------
  831.  
  832. // locate the first track in a movie with the supplied type
  833. Track    GetFirstTrackOfType( Movie    aMovie, OSType    trackType )
  834. {
  835.     Track     theTrack  = nil ; 
  836.     OSType     mediaType;
  837.     short    trackCount ;
  838.     short    index ;
  839.     
  840.     trackCount = GetMovieTrackCount(aMovie);
  841.     for ( index=1 ; index <= trackCount ; index++) {
  842.         Track t = GetMovieIndTrack(aMovie, index);
  843.  
  844.         GetMediaHandlerDescription(GetTrackMedia(t), &mediaType, nil, nil);
  845.         if (mediaType == trackType) {
  846.             theTrack = t;
  847.             break;
  848.         }
  849.     }
  850.  
  851.     return theTrack ;
  852.  
  853. }
  854.  
  855.  
  856. //---------------------------------------------------------------------
  857. //    set the cursor to the correct shape, 
  858. //    according to the current location
  859.     
  860. void     DoAdjustCursor( Point mouse, RgnHandle region, WindowPtr window) 
  861. {
  862.     RgnHandle         arrowRegion, handRegion ;
  863.     Rect            handRect ;
  864.     Point            handTopLeft, handBotRight ;
  865.     DocumentHandle    aDocHdl ;
  866.     
  867.  
  868.     Movie             aMovie ;
  869.     MovieController    aController ;
  870.     
  871.     if( window != nil ) {
  872.     
  873.         // get the movie controller reference from the 
  874.         // RefCon field of the window
  875.     
  876.         if(( aDocHdl = (DocumentHandle)GetWRefCon( window )) != nil) {    
  877.             if( (aController = (**aDocHdl).myController) != nil ) {
  878.             
  879.                                 
  880.                 // get the movie reference from the controller
  881.                 aMovie = MCGetMovie( aController ) ;
  882.                 GetMovieBox( aMovie, &handRect );
  883.                             
  884.                 arrowRegion = NewRgn() ;
  885.                 handRegion = NewRgn() ;
  886.                 
  887.                 // make the arrow region huge
  888.                 SetRectRgn(arrowRegion, -32768,  -32768,  32766,   32766 ) ;
  889.                 
  890.                 // calculate the region for the hand 
  891.             
  892.                 SetPort( window ) ;
  893.                 
  894.                 handTopLeft.h = handRect.left ;
  895.                 handTopLeft.v = handRect.top ;
  896.                 handBotRight.h = handRect.right ;
  897.                 handBotRight.v = handRect.bottom ;
  898.                 
  899.                 LocalToGlobal( &(handTopLeft)) ;
  900.                 LocalToGlobal( &(handBotRight)) ;
  901.                 
  902.                 handRect.left = handTopLeft.h ;
  903.                 handRect.top = handTopLeft.v ;
  904.                 handRect.right = handBotRight.h ;
  905.                 handRect.bottom = handBotRight.v ; 
  906.                 
  907.                 RectRgn( handRegion, &handRect ) ;
  908.                 
  909.                 SetOrigin( -(window->portBits.bounds.left), -(window->portBits.bounds.left)) ;
  910.                 SetOrigin( 0, 0 ) ;
  911.                 
  912.                 // the arrow region is everything else
  913.                 DiffRgn( arrowRegion, handRegion, arrowRegion ) ;
  914.                 
  915.                 if(PtInRgn( mouse, handRegion )) {
  916.                     Cursor        handCsr ;
  917.                     CursHandle    handCursH ;
  918.                     
  919.                     handCursH = GetCursor ( 1024 ) ;
  920.                     handCsr = **handCursH ;
  921.                     
  922.                     SetCursor( &handCsr ) ;
  923.                     CopyRgn( handRegion, region ) ;
  924.                 }
  925.                 
  926.                 if(PtInRgn( mouse, arrowRegion )) {
  927.                     SetCursor( &qd.arrow ) ;
  928.                     CopyRgn( arrowRegion, region ) ;
  929.                 }
  930.         
  931.                 DisposeRgn( arrowRegion ) ;
  932.                 DisposeRgn( handRegion ) ;
  933.             }
  934.         }
  935.     }
  936. }        
  937.  
  938. //---------------------------------------------------------------------
  939. //    Movie controller components allow you to create an action filter function in your 
  940. //    application. The component calls your action filter function whenever an action 
  941. //    occurs in the control. (An action is an integer constant used by the movie controller 
  942. //    omponent.) You can then customize the behavior of the control or simply monitor user 
  943. //    actions. You establish an action filter function by calling the MCSetActionFilter 
  944. //    function.
  945. //    
  946. //    This code  demonstrates the use of an action filter function. This filter function 
  947. //    resizes the window whenever the user hides the controller. Therefore, this example 
  948. //    function handles the mcActionControllerSizeChanged action. Your application should 
  949. //    include a similar action filter function so that you can determine when the user 
  950. //    resizes the controller. This function only supports attached controllers.
  951. //
  952.  
  953. pascal Boolean myMCActionFilter(MovieController mc, short action, void *params, long refCon)
  954. {
  955.     RgnHandle                 controllerRgn;
  956.     Rect                         controllerBox;
  957.     WindowPtr                 movieWindow;
  958.     OSErr                    err ;
  959.     
  960.     switch ( action ) {
  961.     
  962.         case mcActionControllerSizeChanged:
  963.         
  964.             /* size of controller/movie has changed */
  965.             
  966.             movieWindow = (WindowPtr)MCGetControllerPort(mc);
  967.             controllerRgn = MCGetWindowRgn(mc, movieWindow);
  968.             if (controllerRgn != nil) {
  969.                 controllerBox = (**controllerRgn).rgnBBox;
  970.                 DisposeRgn (controllerRgn);
  971.                 SizeWindow (movieWindow, controllerBox.right,
  972.                                  controllerBox.bottom, true);
  973.             }
  974.             
  975.             break;
  976.         
  977.         case mcActionMouseDown:
  978.             {
  979.                 EventRecord     *event;
  980.                 Rect            contentArea ;
  981.                 Boolean            goLeft ;                // rotate the movie left
  982.                 Rect            controllerRect ;         // the rect occupied by the controller
  983.  
  984.                 Movie aMovie ;
  985.                                 
  986.                 // get the movie reference from the controller
  987.                 aMovie = MCGetMovie( mc ) ;
  988.                 GetMovieBox( aMovie, &contentArea );
  989.                 
  990.                 event = (EventRecord *)params ;
  991.                 
  992.                 // check to see if we clicked in the controller itself
  993.                 // this will break if the controller is non rectangular
  994.                 
  995.                 movieWindow = (WindowPtr)MCGetControllerPort(mc);
  996.                 controllerRgn = MCGetWindowRgn( mc, movieWindow );
  997.                 if (controllerRgn != nil) {
  998.                     controllerBox = (**controllerRgn).rgnBBox;
  999.                     
  1000.                     // here is the box containing the controller, use this for hit testing on the controller
  1001.                     controllerRect.top = contentArea.bottom ;
  1002.                     controllerRect.left = 0 ;
  1003.                     controllerRect.bottom = controllerBox.bottom ;
  1004.                     controllerRect.right = controllerBox.right ;
  1005.                     
  1006.                     // we only want to process the event iff the event was 
  1007.                     // NOT in the movie controller for this movie
  1008.  
  1009.                     if(! PtInRect ( event->where, &controllerRect ) ) {
  1010.                     
  1011.                         // set our cursor to the grabber
  1012.                         Cursor        handCsr ;
  1013.                         CursHandle    handCursH ;
  1014.                         
  1015.                         handCursH = GetCursor ( 1025 ) ;
  1016.                         handCsr = **handCursH ;
  1017.                         
  1018.                         SetCursor( &handCsr ) ;
  1019.                         
  1020.                         do {
  1021.     
  1022.  
  1023.                             // i guess the user clicked in the content region of the movie
  1024.                             goLeft = (event->where.h > (contentArea.right / 2)) ;                        
  1025.                             
  1026.                             if( goLeft ) {
  1027.                                 // want to step one frame back
  1028.                                 err = MCDoAction (mc, mcActionStep, (Ptr) (-1L));
  1029.                             }
  1030.                             else {
  1031.                                 err = MCDoAction (mc, mcActionStep, (Ptr) (1L));
  1032.                             }
  1033.                             
  1034.                             // draw the next frame
  1035.                             
  1036.                             err = MCDoAction (mc, mcActionDraw, (Ptr) movieWindow);
  1037.                             GetMouse( &(event->where)) ;
  1038.                             
  1039.                         }  while( StillDown()) ;
  1040.  
  1041.                         event = nil ;    
  1042.                     }
  1043.                     DisposeRgn (controllerRgn);
  1044.                 }
  1045.             }
  1046.             break ;
  1047.     }
  1048.     return false;
  1049. }
  1050.  
  1051.  
  1052. //---------------------------------------------------------------------
  1053. // main - entry point for the app.
  1054.  
  1055. void main (void)
  1056. {
  1057.     InitMac() ;
  1058.     MainEventLoop() ;
  1059. }
  1060.